using graver.CodeAnalysis.Syntax;

namespace graver.CodeAnalysis.Binding;

internal sealed class BoundUnaryOperator
{
    public SyntaxKind SyntaxKind { get; }
    public BoundUnaryOperatorKind Kind { get; }
    public Type OperandType { get; }
    public Type ResultType { get; }

    private BoundUnaryOperator(SyntaxKind syntaxKind, BoundUnaryOperatorKind kind, Type operandType) : this(syntaxKind,
        kind, operandType, operandType)
    {
        SyntaxKind = syntaxKind;
        Kind = kind;
        OperandType = operandType;
    }

    private BoundUnaryOperator(SyntaxKind syntaxKind, BoundUnaryOperatorKind kind, Type operandType, Type resultType)
    {
        SyntaxKind = syntaxKind;
        Kind = kind;
        OperandType = operandType;
        ResultType = resultType;
    }

    private static readonly BoundUnaryOperator[] Operators =
    {
        new(SyntaxKind.BangToken, BoundUnaryOperatorKind.LogicNegation, typeof(bool)),
        new(SyntaxKind.PlusToken, BoundUnaryOperatorKind.Identity, typeof(int)),
        new(SyntaxKind.MinusToken, BoundUnaryOperatorKind.Negation, typeof(int)),
    };

    public static BoundUnaryOperator Bind(SyntaxKind syntaxKind, Type operandType)
    {
        return Operators.FirstOrDefault(op => op.SyntaxKind == syntaxKind && op.OperandType == operandType);
    }
}
